Guide d’utilisation des données de projection d’emploi

Format HTML

Auteur·rice

J. Gelb – RVD – ARTM

Date de publication

22 juillet 2026

Objectif
Ce document illustre comment utiliser les données de projections d’emplois réalisées par l’ARTM. Il explique notamment la distinction entre le fichier projection_emplois_ZAT_ARTM.csv qui fournit des point wise estimate pour des scénarios optimiste, pessimiste et intermédiaire, et le fichier projection_emplois_ZAT_ARTM_samples.csv qui fournit des échantillons de la distribution prédictive postérieure.
Mises-à-jour
Dernière compilation
2026-07-22

1 Introduction

L’ARTM utilise un modèle statistique tendanciel basé sur des données de Statistique Canada, le rôle foncier, l’utilisation du sol et les infrastructures de transport pour prédire le nombre d’emplois attendu dans des Zones d’Analyse en Transport (ZAT).

Le modèle statistique est un modèle bayésien. Ce type de modèle permet d’obtenir la distribution complète des prédictions réalisées par le modèle. En effet, la prédiction d’un modèle statistique est toujours caractérisée par une certaine incertitude.

Le fichier projection_emplois_ZAT_ARTM.csv donne accès à des résumés statistiques par ZAT selon trois scénarios:

  • le scénario de référence qui correspond au 58e percentile de la distribution postérieur (sélectionné pour minimiser les erreurs dans un exercice de cross-validation). Ces valeurs correspondent à une prédiction raisonnable pour l’ensemble des ZAT
  • le scénario pessimiste, soit le 54e percentile. Il correspond à une prédiction plus faible pour l’ensemble des ZAT simultanément.
  • le scénario optimiste, soit le 64e percentile. Il correspond à une prédiction plus forte pour l’ensemble des ZAT simultanément.

Les scénarios ont pour objectif de donner pour chaque ZAT une idée de la variation crédible du nombre d’emplois prédit par le modèle. Les comparaisons des valeurs des scénarios ne sont cohérentes que pour une même ZAT. Ces valeurs ne sont pas additives au sens propre. Par exemple, il serait erroné d’additionner toutes les valeurs des scénarios pessimistes d’une région pour obtenir le scénario pessimiste de cette région.

Lorsque les données doivent être agrégées ou subir une transformation et tout particulièrement lorsqu’une mesure de l’incertitude doit être obtenue, il est important d’utiliser les échantillons de la distribution prédictive postérieure issue du modèle. À partir de ces échantillons, il devient possible de faire des agrégations valides.

Les échantillons de la distribution prédictive postérieure sont un ensemble de réalisations possibles de l’emploi futur, intégrant l’incertitude du modèle (paramètres et bruit prédictif). Ils sont indispensables pour quantifier les risques, produire des intervalles de crédibilité et faire de l’analyse de scénarios.

Nous illustrons ci-dessous comment utiliser ces données en agrégeant les volumes d’emplois par région.

2 Approche erronée (À ne pas faire !)

Une approche naïve et eronées serait d’utiliser les données de type point wise estimate et de les agréger directement. Cela reviendrait à créer des situations très exagérées pour les limites de l’estimation de l’incertitude.

library(data.table, quietly = TRUE)
library(dplyr, quietly = TRUE)
library(collapse, quietly = TRUE)
library(sf, quietly = TRUE)
library(ggplot2, quietly = TRUE)
library(ARThemis, quietly = TRUE)

# Chargement des données
emplois_pwe <- read.csv("ajustement du modèle/projection_emplois_ZAT_ARTM.csv")

# combinaison des données par région et par année
data1 <- emplois_pwe |> 
  fgroup_by(AN, nomreg) |> 
  fsummarise(
    emploi_reel = fsum(Y1, na.rm = T),
    proj_med = fsum(s1_med, na.rm = T),
    proj_low = fsum(s1_low, na.rm = T),
    proj_high = fsum(s1_high, na.rm = T)
  )

# séparation des données observées et des projections
real <- subset(data1, data1$AN < 2021)
real_2016 <- subset(real, real$AN == 2016)
real_2016$proj_med <- real_2016$emploi_reel
real_2016$proj_low <- real_2016$emploi_reel
real_2016$proj_high <- real_2016$emploi_reel

proj <- data1 |> 
  fsubset(AN > 2016) |> 
  rbind(real_2016)

# représentation finale

ggplot() + 
  geom_line(data = real, 
             mapping = aes(x = AN, y = emploi_reel, 
                           group = nomreg, color = nomreg)) +
  geom_point(data = real, 
             mapping = aes(x = AN, y = emploi_reel, color = nomreg)) + 
  geom_ribbon(data = proj, 
             mapping = aes(x = AN, ymin = proj_low,
                           ymax = proj_high, group = nomreg),
             alpha = 0.2) +
  geom_line(data = proj, 
             mapping = aes(x = AN, y = proj_med ,group = nomreg, color = nomreg)) +
  geom_point(data = proj, 
             mapping = aes(x = AN, y = proj_med, color = nomreg)) +
  gg_theme_artm() +
  labs(
    x = "",
    y = "volume d'emploi",
    color = "Région"
  ) + 
  scale_y_continuous(labels = function(x){format(x, scientific = FALSE, big.mark = " ")})

3 Approche valide

Si nous voulons déterminer correctement notre degré d’incertitude quant au nombre d’emplois par région, nous devons utiliser les échantillons de la distribution prédictive postérieure. Dans les données fournies, 1500 échantillons sont disponibles pour chaque année et chaque ZAT. Ils permettent de décrire toute l’incertitude de prédiction pour chaque ZAT.

Prenons un exemple avec une ZAT spécifique.

# Chargement des données
emplois_pps <- fread("ajustement du modèle/projection_emplois_ZAT_ARTM_samples.csv")
emplois_pps <- data.frame(emplois_pps)

# observations d'une ZAT pour les années de projection
exemple1 <- emplois_pps |>
  fsubset(AN > 2016) |> 
  fsubset(idzat == 178) |> 
  fmutate(
    Y1 = NULL,
    idzone = NULL,
    nomreg = NULL
  ) |> 
  pivot(ids = c("AN", "idzat"), how = "longer")

ggplot(exemple1) + 
  geom_histogram(aes(x = value), bins = 30) + 
  facet_wrap(vars(AN)) + 
  xlim(0, quantile(exemple1$value, probs = 0.99)) + 
  gg_theme_artm() + 
  labs(y = "", x = "emplois")

Pour cette ZAT spécifique, les prédictions se concentrent autour de 500 et 750 emplois, mais le modèle n’exclut pas des valeurs plus extrêmes.

Pour agréger correctement cette information, il faut agréger les données pour chaque échantillon postérieur, et ensuite calculer des intervalles de crédibilité sur les distributions obtenues.

# agrégation par région

prep_data1 <- emplois_pps |> 
  fsubset(AN > 2016) |>
  fmutate(
    Y1 = NULL,
    idzone = NULL
  ) |> 
  pivot(ids = c('AN', 'nomreg', "idzat"), how = 'longer') |> 
  fgroup_by(AN, nomreg, variable) |>
  fsummarise(
    emplois = fsum(value, na.rm = T)
  ) |> 
  fungroup() |> 
  fgroup_by(AN, nomreg) |> 
  fsummarise(
    med = fquantile(emplois, probs = 0.5),
    qtl_10 = fquantile(emplois, probs = 0.1),
    qtl_20 = fquantile(emplois, probs = 0.2),
    qtl_30 = fquantile(emplois, probs = 0.3),
    qtl_40 = fquantile(emplois, probs = 0.4),
    qtl_60 = fquantile(emplois, probs = 0.6),
    qtl_70 = fquantile(emplois, probs = 0.7),
    qtl_80 = fquantile(emplois, probs = 0.8),
    qtl_90 = fquantile(emplois, probs = 0.9)
  )

prep_data1$emploi_reel <- NA

data1$proj_med <- NULL
data1$proj_low <- NULL
data1$proj_high <- NULL

real <- subset(data1, data1$AN < 2021)

to_add <- c("med", "qtl_10", "qtl_20", "qtl_30", "qtl_40", 
            "qtl_60", "qtl_70", "qtl_80", "qtl_90")

for(var in to_add){
  real[[var]] <- real$emploi_reel
}

proj <- rbind(prep_data1, real)


ggplot(subset(proj, proj$nomreg != "MONTREAL CENTRE")) + 
  geom_ribbon(aes(
    x = AN, ymin = qtl_10, ymax = qtl_90, group = nomreg
  ), alpha = 0.2) +
  geom_ribbon(aes(
    x = AN, ymin = qtl_20, ymax = qtl_80, group = nomreg
  ), alpha = 0.2) +
  geom_ribbon(aes(
    x = AN, ymin = qtl_30, ymax = qtl_70, group = nomreg
  ), alpha = 0.2) +
  geom_ribbon(aes(
    x = AN, ymin = qtl_40, ymax = qtl_60, group = nomreg
  ), alpha = 0.2) +
  geom_line(aes(x = AN, y = med, color = nomreg)) + 
  geom_vline(xintercept = 2016, linetype = "dashed") + 
  scale_x_continuous(breaks = unique(proj$AN)) + 
  gg_theme_artm(base_size = 10) + 
  labs(color = "Région", x = "", y = "volume d'emploi") + 
  scale_y_continuous(labels = function(x){format(x, scientific = FALSE, big.mark = " ")})

La figure ci-dessus illustre la distribution complète de l’incertitude des projections d’emplois au niveau des régions. Chaque zone grisée représente un intervalle de crédibilité plus grand (10-90%, 20-80%, 30-70% et 40-60%).

Nous avons réalisé ici des agréations spatiales, mais la logique serait identique pour des agrégations temporelles, ou tout autre type de processus.

Par exemple, un second modèle qui utiliserait ces données entrées devrait être répliqué un grand nombre de fois sur différents échantillons postérieurs pour ensuite disposer d’une distribution complète des paramètres finaux. Ce processus se nomme la propagation de l’incertitude.

Nous donnons ci-dessous un deuxième exemple pour calculer le taux de croissance annuel par région entre 2016 et 2041.

# agrégation par région

draw_cols <- paste0("sample_",1:1500)

reg_tots <- emplois_pps |> 
  fgroup_by(AN, nomreg) |> 
  fsummarise(across(c("Y1", draw_cols), .fns = fsum, na.rm = T))

tots_2016 <- reg_tots |> 
  fsubset(AN == 2016) |> 
  fselect(c("nomreg", "Y1"))

tots_2041 <- reg_tots |> 
  fsubset(AN == 2041) |> 
  fselect(c("AN", "nomreg", draw_cols)) |>
  pivot(ids = c("AN", "nomreg")) |> 
  join(tots_2016, on = c("nomreg"), verbose = FALSE) |> 
  fmutate(
    tx_croiss = ((value / Y1)**(1/(2041-2016)) - 1) * 100
  )

tots_2041 |> 
  fsubset(tx_croiss > fquantile(tx_croiss, probs = 0.01)) |> 
  fsubset(tx_croiss < fquantile(tx_croiss, probs = 0.99)) |> 
  ggplot() + 
    geom_violin(aes(y = nomreg, x = tx_croiss, 
                    fill = nomreg)) + 
    geom_boxplot(aes(y = nomreg, x = tx_croiss),
                 width = 0.2, outliers = FALSE) + 
  gg_theme_artm(legend.position = "none") + 
  labs(
    y = "", 
    x = "taux de croissance moyen annuel"
  )

Les graphiques en violons donnent une description complète de la distribution attendue du taux de croissance moyen. Pour faciliter la lecture, il est possible de calculer un simple tableau avec des intervalles de crédibilité (ici à 80%).

tots_2041 |> 
  fgroup_by(nomreg) |> 
  fsummarise(
    med = fquantile(tx_croiss, probs = 0.5),
    low = fquantile(tx_croiss, probs = 0.10),
    high = fquantile(tx_croiss, probs = 0.90)
  ) |> 
  knitr::kable(
    digits = 2,
    format = "html",
    col.names = c("région",
                  "tx. croiss. (50%)", 
                   "tx. croiss. (10%)",
                   "tx. croiss. (90%)") 
  )
région tx. croiss. (50%) tx. croiss. (10%) tx. croiss. (90%)
COURONNE NORD 0.69 0.36 1.28
COURONNE SUD 0.70 0.34 1.25
LAVAL 0.52 0.11 1.09
LONGUEUIL 0.42 0.04 0.93
MONTREAL CENTRE 0.28 0.05 0.65
MONTREAL EST 0.65 0.25 1.17
MONTREAL OUEST 0.46 0.18 0.81